package com.ys.day30.p4XML解析与配置;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.xml.parsers.SAXParser;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述: Socket网络编程的XML配置文件工具类
 *
 * @author CodeYang
 * @version 2021/1/14 15:56
 */
final  public class SocketUtils {

    private SocketUtils() {
    }

    /**
     * DOM4J 解析其内部的 DOM树
     */
    private static Document document;

    /**
     *  将Document 树中的信息添加的到map集合中,
     *  注意:由于我的操作在整个项目中只执行一次 所以定义static 关键字修饰
     */
    private static Map<String,SocketBean> socketMap = new ConcurrentHashMap<>(16);

    /**
     * 操作步骤:
     * 1: xml -> io ->document -> map
     */
    static {
        try(
                // xml _ io
                InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("data.xml")
        )
         {
             // io -> document
             if (null == inputStream){
                 throw new RuntimeException("配置文件加载失败");
             }
             // 解析xml 将数据存储到 dom树中
             SAXReader sr = new SAXReader();
             document = sr.read(inputStream);
             // 3 遍历节点 ,将数据存储到 map集合中
             // document -> map
             documentMap();

         }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 遍历DOM树,将节点数据存储到map集合
     * step:
     * 1 获取DOM根节点
     * 2 获取根节点下的所有 socket 子节点
     * 3 遍历所有子节点
     * 4 获取每个socket 节点 id属性值 作为key
     * 5 获取每个socket 下的 address 与 port值
     * 6 封装map
     */
    private static void documentMap() {
        /**
         * 获取Root节点
         */
        Element rootElement = document.getRootElement();
        /**
         * 遍历根节点下面的所有的子节点
         */
        List<Element> list = rootElement.elements();
        for (Element element : list) {
            // 获得 每个bean的 id 属性
            String id = element.attributeValue("id");
            // 获取 socket 下面address和port
            Element addressElement = element.element("address");
            Element portElement = element.element("port");
            // 获取节点的文本值,并且转换值
            String address = addressElement.getText();
            String port = portElement.getText();

            socketMap.put(id,new SocketBean(address,Integer.parseInt(port)));

        }
    }

    /**
     * 提供一个暴露方法,用于获取map集合中的数据
     * @param key
     * @return 返回一个socketbean对象
     */
    public static SocketBean getSocketBean(String key){
        return socketMap.get(key);
    }
}
